package com.foreveross.bsl.push.web.controllers;

import java.util.Map;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.foreveross.bsl.common.utils.mapper.BeanMapper;
import com.foreveross.bsl.common.utils.web.QuerySpecs;
import com.foreveross.bsl.common.utils.web.model.QueryModelHelper;
import com.foreveross.bsl.common.utils.web.model.SelectBoxModel;
import com.foreveross.bsl.common.utils.web.model.SortInfoModel;
import com.foreveross.bsl.push.application.AppChannelConfigService;
import com.foreveross.bsl.push.application.PushMgmtService;
import com.foreveross.bsl.push.application.PushService;
import com.foreveross.bsl.push.application.TagSummaryService;
import com.foreveross.bsl.push.application.vo.MessageParams;
import com.foreveross.bsl.push.application.vo.MessageVo;
import com.foreveross.bsl.push.application.vo.ModuleMessage;
import com.foreveross.bsl.push.application.vo.PushRequestVo;
import com.foreveross.bsl.push.application.vo.PushVo;
import com.foreveross.bsl.push.application.vo.TagSummaryVo;
import com.foreveross.bsl.push.web.PageMustache;
import com.foreveross.bsl.push.web.controllers.form.MessageSubmitForm;
import com.google.common.collect.Maps;

@Controller
@RequestMapping(value = "/push")
public class PushController extends PushBaseController {

	@Inject
	private PushService pushService;

	@Inject
	private PushMgmtService pushQueryService;

	@Inject
	private TagSummaryService tagSumService;

	@Inject
	private AppChannelConfigService configService;

	@RequestMapping("")
	public String listRequest(@RequestParam(value = "page", defaultValue = "1") int pageNumber,
			@RequestParam(value = "page.size", defaultValue = PAGE_SIZE) int pageSize, 
			Model model, HttpServletRequest request) {

		String queryUrl="/push";
		QueryModelHelper queryHelper=new QueryModelHelper(queryUrl, makeQueryFields(), makeSortInfo());
		QuerySpecs querySpecs=queryHelper.populateQueryModel(model, request);
		
		Page<PushRequestVo> prs = pushQueryService.findPushRequests(pageNumber, pageSize, querySpecs);
		model.addAttribute("pushRequests", prs);
		model.addAttribute("page", new PageMustache(prs, PAGINATION_SIZE));

		return "push/request-list";
	}
	
	private final SelectBoxModel makeQueryFields(){
		SelectBoxModel sbm=new SelectBoxModel();
		//option的key组成：操作表示符_条件字段，必须是操作表示符开始，
		//操作表示有EQ, LIKE, GT, LT, GTE, LTE 分别表示等于，like，大于，小于，大于等于，小于等于
		//条件字段为entity类映射到mongoDB字段名，即@Field注解里的名字。
		sbm.addOption("EQ_submit_time", "提交时间", true);
		sbm.addOption("EQ_receiver_type", "发送方式");
		return sbm;
	}
	
	private final SortInfoModel makeSortInfo(){
		SortInfoModel sim=new SortInfoModel();
		//排序字段为entity类映射到mongoDB字段名，即@Field注解里的名字。
		sim.setSortEntry("submit_time", "提交时间", false);
		return sim;
	}
	
	@RequestMapping("requests-by-app/{appId}")
	public String listRequestByAppId(@RequestParam(value = "page", defaultValue = "1") int pageNumber,
			@RequestParam(value = "page.size", defaultValue = PAGE_SIZE) int pageSize,
			@PathVariable("appId") String appId,
			Model model){
		
		Page<PushRequestVo> prs = pushQueryService.findPushRequestsByApp(appId, pageNumber, pageSize, QuerySpecs.EMPTY_QUERY_SPECS);
		model.addAttribute("pushRequests", prs);
		model.addAttribute("page", new PageMustache(prs, PAGINATION_SIZE));
		return "push/request-list";
	}

	@RequestMapping(value = "{requestId}")
	public String listPushs(@RequestParam(value = "page", defaultValue = "1") int pageNumber,
			@RequestParam(value = "page.size", defaultValue = PAGE_SIZE) int pageSize,
			@PathVariable("requestId") String requestId,
			Model model, HttpServletRequest request) {
		Page<PushVo> pushs = pushQueryService.findPushsByRequest(requestId, pageNumber, pageSize, QuerySpecs.EMPTY_QUERY_SPECS);
		model.addAttribute("pushs", pushs);
		model.addAttribute("page", new PageMustache(pushs, PAGINATION_SIZE));
		return "push/push-list";
	}
	
	@RequestMapping(value = "appid", method = RequestMethod.GET)
	public String inputAppIdForm(RedirectAttributes redirectAttributes){
		return "push/appid-form";
	}
	
	@RequestMapping(value = "create", method = RequestMethod.GET)
	public String creatForm(@RequestParam("appId") String appId, Model model, RedirectAttributes redirectAttributes) {
		if(configService.existsConfig(appId)){
			TagSummaryVo tagSum = this.tagSumService.getTagSummary(appId);
			model.addAttribute("tagSum", tagSum);
			model.addAttribute("msg", new MessageVo());
			model.addAttribute("appId", appId);
			return "push/push-form";
		}
		else{
			redirectAttributes.addAttribute("appId", appId);
			redirectAttributes.addAttribute("create", true);
			redirectAttributes.addAttribute("redirect", "redirect:/push/create");
			return "redirect:/push/config/channel";
		}
	}

	@RequestMapping(value = "create", method = RequestMethod.POST)
	public @ResponseBody Map<String, Object> create(MessageSubmitForm form) {
		MessageParams msgParams=BeanMapper.map(form, MessageParams.class);
		if(form.getExtras()!=null){
			msgParams.getMessage().setExtras(form.getExtras());
		}
		msgParams.validate();
		if(MessageVo.MessageTypeEnum.MODULE.equals(msgParams.getMessage().getMessageType())){
			if(StringUtils.isEmpty(form.getModuleIdentifer())){
				throw new IllegalArgumentException("模块消息的moduleIdentifer不能为空");
			}
			msgParams.getMessage().putExtra(ModuleMessage.KEY_MODULE_ID, form.getModuleIdentifer());
		}
		msgParams.setSubmitUserId(this.getCurrentUserId());
		String pushRequestId=this.pushService.submitMessage(msgParams);
		Map<String, Object> result=Maps.newHashMap();
		result.put("result", true);
		result.put("pushRequestId", pushRequestId);
		return result;
	}
}
